import React, { useState, useEffect } from 'react'
import { X, Check, X as XIcon, RotateCcw, Eye, EyeOff, Copy, Download } from 'lucide-react'

export interface DiffSegment {
  type: 'unchanged' | 'added' | 'removed'
  content: string
  position: number
}

export interface DiffModalProps {
  isOpen: boolean
  onClose: () => void
  originalText: string
  modifiedText: string
  operation: string
  onAccept: (modifiedText: string) => void
  onReject: () => void
  onRetry?: () => void
  metadata?: {
    provider?: string
    model?: string
    tokensUsed?: number
    cost?: number
    responseTime?: number
  }
}

const DiffModal: React.FC<DiffModalProps> = ({
  isOpen,
  onClose,
  originalText,
  modifiedText,
  operation,
  onAccept,
  onReject,
  onRetry,
  metadata
}) => {
  const [diffSegments, setDiffSegments] = useState<DiffSegment[]>([])
  const [showSideBySide, setShowSideBySide] = useState(true)
  const [isProcessing, setIsProcessing] = useState(false)
  const [selectedChanges, setSelectedChanges] = useState<Set<number>>(new Set())
  const [showStats, setShowStats] = useState(true)

  useEffect(() => {
    if (isOpen) {
      calculateDiff()
    }
  }, [originalText, modifiedText, isOpen])

  const calculateDiff = () => {
    const segments = computeTextDiff(originalText, modifiedText)
    setDiffSegments(segments)
    // 默认选择所有变更
    const changeIndices = segments
      .map((seg, idx) => seg.type !== 'unchanged' ? idx : -1)
      .filter(idx => idx !== -1)
    setSelectedChanges(new Set(changeIndices))
  }

  const computeTextDiff = (text1: string, text2: string): DiffSegment[] => {
    // 简单的逐行差异计算
    const lines1 = text1.split('\n')
    const lines2 = text2.split('\n')
    const segments: DiffSegment[] = []

    let i = 0, j = 0
    let position = 0

    while (i < lines1.length || j < lines2.length) {
      if (i >= lines1.length) {
        // 只在目标文本中存在
        segments.push({
          type: 'added',
          content: lines2[j] + '\n',
          position
        })
        position += lines2[j].length + 1
        j++
      } else if (j >= lines2.length) {
        // 只在源文本中存在
        segments.push({
          type: 'removed',
          content: lines1[i] + '\n',
          position
        })
        position += lines1[i].length + 1
        i++
      } else if (lines1[i] === lines2[j]) {
        // 相同行
        segments.push({
          type: 'unchanged',
          content: lines1[i] + '\n',
          position
        })
        position += lines1[i].length + 1
        i++
        j++
      } else {
        // 不同行
        segments.push({
          type: 'removed',
          content: lines1[i] + '\n',
          position
        })
        segments.push({
          type: 'added',
          content: lines2[j] + '\n',
          position
        })
        position += Math.max(lines1[i].length, lines2[j].length) + 1
        i++
        j++
      }
    }

    return segments
  }

  const handleAcceptChanges = async () => {
    setIsProcessing(true)
    try {
      // 构建只包含选定变更的文本
      const acceptedText = buildAcceptedText()
      await onAccept(acceptedText)
    } catch (error) {
      console.error('Accepting changes failed:', error)
    } finally {
      setIsProcessing(false)
    }
  }

  const buildAcceptedText = (): string => {
    let result = ''
    diffSegments.forEach((segment, index) => {
      if (segment.type === 'unchanged' || selectedChanges.has(index)) {
        result += segment.content
      }
    })
    return result
  }

  const toggleChangeSelection = (index: number) => {
    const newSelection = new Set(selectedChanges)
    if (newSelection.has(index)) {
      newSelection.delete(index)
    } else {
      newSelection.add(index)
    }
    setSelectedChanges(newSelection)
  }

  const selectAllChanges = () => {
    const changeIndices = diffSegments
      .map((seg, idx) => seg.type !== 'unchanged' ? idx : -1)
      .filter(idx => idx !== -1)
    setSelectedChanges(new Set(changeIndices))
  }

  const deselectAllChanges = () => {
    setSelectedChanges(new Set())
  }

  const copyToClipboard = () => {
    navigator.clipboard.writeText(buildAcceptedText())
  }

  const downloadDiff = () => {
    const diffContent = generateDiffReport()
    const blob = new Blob([diffContent], { type: 'text/plain' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `diff-${operation}-${Date.now()}.txt`
    a.click()
    URL.revokeObjectURL(url)
  }

  const generateDiffReport = (): string => {
    let report = `差异对比报告\n`
    report += `操作: ${operation}\n`
    report += `时间: ${new Date().toLocaleString()}\n`
    if (metadata) {
      report += `提供商: ${metadata.provider || '未知'}\n`
      report += `模型: ${metadata.model || '未知'}\n`
      report += `Token使用: ${metadata.tokensUsed || 0}\n`
      report += `成本: $${metadata.cost?.toFixed(4) || '0.0000'}\n`
      report += `响应时间: ${metadata.responseTime || 0}ms\n`
    }
    report += `\n原始文本:\n${originalText}\n\n修改后文本:\n${modifiedText}\n\n差异详情:\n`

    diffSegments.forEach((segment, index) => {
      const prefix = segment.type === 'added' ? '+ ' :
                    segment.type === 'removed' ? '- ' : '  '
      report += `${prefix}${segment.content.replace(/\n$/, '')}\n`
    })

    return report
  }

  const getStatistics = () => {
    const addedLines = diffSegments.filter(s => s.type === 'added').length
    const removedLines = diffSegments.filter(s => s.type === 'removed').length
    const unchangedLines = diffSegments.filter(s => s.type === 'unchanged').length
    const selectedAdded = diffSegments.filter((s, i) => s.type === 'added' && selectedChanges.has(i)).length
    const selectedRemoved = diffSegments.filter((s, i) => s.type === 'removed' && selectedChanges.has(i)).length

    return {
      addedLines,
      removedLines,
      unchangedLines,
      selectedAdded,
      selectedRemoved,
      totalChanges: addedLines + removedLines,
      selectedChanges: selectedAdded + selectedRemoved
    }
  }

  const stats = getStatistics()

  if (!isOpen) return null

  return (
    <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
      <div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-6xl max-h-[90vh] overflow-hidden">
        {/* Header */}
        <div className="flex items-center justify-between p-6 border-b border-gray-200 dark:border-gray-700">
          <div>
            <h2 className="text-xl font-semibold text-gray-900 dark:text-gray-100">
              AI修改确认 - {operation}
            </h2>
            <p className="text-sm text-gray-600 dark:text-gray-400 mt-1">
              请检查并选择要应用的更改
            </p>
          </div>
          <div className="flex items-center gap-2">
            <button
              onClick={() => setShowStats(!showStats)}
              className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
              title={showStats ? '隐藏统计' : '显示统计'}
            >
              <Eye className="w-4 h-4 text-gray-500 dark:text-gray-400" />
            </button>
            <button
              onClick={() => setShowSideBySide(!showSideBySide)}
              className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
              title={showSideBySide ? '统一视图' : '并排对比'}
            >
              <RotateCcw className="w-4 h-4 text-gray-500 dark:text-gray-400" />
            </button>
            <button
              onClick={onClose}
              className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
            >
              <X className="w-5 h-5 text-gray-500 dark:text-gray-400" />
            </button>
          </div>
        </div>

        {/* Statistics Bar */}
        {showStats && (
          <div className="px-6 py-3 bg-blue-50 dark:bg-blue-900/20 border-b border-blue-200 dark:border-blue-800">
            <div className="flex items-center justify-between text-sm">
              <div className="flex items-center gap-6">
                <span className="text-blue-600 dark:text-blue-400">
                  +{stats.selectedAdded} / {stats.addedLines} 新增行
                </span>
                <span className="text-red-600 dark:text-red-400">
                  -{stats.selectedRemoved} / {stats.removedLines} 删除行
                </span>
                <span className="text-gray-600 dark:text-gray-400">
                  {stats.unchangedLines} 未改变行
                </span>
              </div>
              <div className="flex items-center gap-4">
                {metadata && (
                  <div className="text-xs text-gray-500 dark:text-gray-400">
                    {metadata.provider} • {metadata.model} • {metadata.tokensUsed} tokens • ${metadata.cost?.toFixed(4)}
                  </div>
                )}
              </div>
            </div>
          </div>
        )}

        {/* Control Bar */}
        <div className="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-2">
              <button
                onClick={selectAllChanges}
                className="px-3 py-1 text-sm bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors"
              >
                全选
              </button>
              <button
                onClick={deselectAllChanges}
                className="px-3 py-1 text-sm bg-gray-500 text-white rounded hover:bg-gray-600 transition-colors"
              >
                全不选
              </button>
              <div className="text-sm text-gray-600 dark:text-gray-400 ml-4">
                已选择 {stats.selectedChanges} / {stats.totalChanges} 项更改
              </div>
            </div>
            <div className="flex items-center gap-2">
              <button
                onClick={copyToClipboard}
                className="p-2 hover:bg-gray-200 dark:hover:bg-gray-700 rounded transition-colors"
                title="复制结果"
              >
                <Copy className="w-4 h-4 text-gray-600 dark:text-gray-400" />
              </button>
              <button
                onClick={downloadDiff}
                className="p-2 hover:bg-gray-200 dark:hover:bg-gray-700 rounded transition-colors"
                title="下载差异报告"
              >
                <Download className="w-4 h-4 text-gray-600 dark:text-gray-400" />
              </button>
            </div>
          </div>
        </div>

        {/* Diff Content */}
        <div className="flex-1 overflow-hidden">
          {showSideBySide ? (
            // Side-by-side view
            <div className="flex h-[60vh]">
              {/* Original */}
              <div className="flex-1 border-r border-gray-200 dark:border-gray-700 overflow-y-auto">
                <div className="bg-gray-50 dark:bg-gray-900 px-4 py-2 border-b border-gray-200 dark:border-gray-700">
                  <h3 className="font-medium text-gray-700 dark:text-gray-300">原始文本</h3>
                </div>
                <div className="p-4 font-mono text-sm whitespace-pre-wrap">
                  {originalText}
                </div>
              </div>

              {/* Modified */}
              <div className="flex-1 overflow-y-auto">
                <div className="bg-gray-50 dark:bg-gray-900 px-4 py-2 border-b border-gray-200 dark:border-gray-700">
                  <h3 className="font-medium text-gray-700 dark:text-gray-300">修改后文本</h3>
                </div>
                <div className="p-4 font-mono text-sm whitespace-pre-wrap">
                  {modifiedText}
                </div>
              </div>
            </div>
          ) : (
            // Unified diff view
            <div className="h-[60vh] overflow-y-auto">
              <div className="p-4 font-mono text-sm">
                {diffSegments.map((segment, index) => (
                  <div
                    key={index}
                    className={`flex items-start gap-2 ${
                      segment.type === 'added' ? 'bg-green-50 dark:bg-green-900/20' :
                      segment.type === 'removed' ? 'bg-red-50 dark:bg-red-900/20' :
                      'bg-white dark:bg-gray-800'
                    }`}
                  >
                    {segment.type !== 'unchanged' && (
                      <input
                        type="checkbox"
                        checked={selectedChanges.has(index)}
                        onChange={() => toggleChangeSelection(index)}
                        className="mt-1 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
                      />
                    )}
                    <div className="flex-1">
                      <span className={`inline-block w-8 text-center ${
                        segment.type === 'added' ? 'text-green-600' :
                        segment.type === 'removed' ? 'text-red-600' :
                        'text-gray-400'
                      }`}>
                        {segment.type === 'added' ? '+' :
                         segment.type === 'removed' ? '-' : ' '}
                      </span>
                      <span className={
                        segment.type === 'added' ? 'text-green-700 dark:text-green-300' :
                        segment.type === 'removed' ? 'text-red-700 dark:text-red-300' :
                        'text-gray-700 dark:text-gray-300'
                      }>
                        {segment.content || '\u00A0'}
                      </span>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          )}
        </div>

        {/* Footer */}
        <div className="flex items-center justify-between p-6 border-t border-gray-200 dark:border-gray-700">
          <div className="flex items-center gap-3">
            <button
              onClick={onReject}
              className="px-4 py-2 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
            >
              拒绝更改
            </button>
            {onRetry && (
              <button
                onClick={onRetry}
                className="px-4 py-2 text-yellow-700 dark:text-yellow-300 hover:bg-yellow-100 dark:hover:bg-yellow-900/20 rounded-lg transition-colors"
              >
                重新生成
              </button>
            )}
          </div>
          <button
            onClick={handleAcceptChanges}
            disabled={isProcessing || selectedChanges.size === 0}
            className="flex items-center gap-2 px-6 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors"
          >
            {isProcessing ? (
              <>
                <div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" />
                处理中...
              </>
            ) : (
              <>
                <Check className="w-4 h-4" />
                应用 {selectedChanges.size} 项更改
              </>
            )}
          </button>
        </div>
      </div>
    </div>
  )
}

export default DiffModal